/**
 * 包装原始数据
 */
class Entry {
    constructor(data, timestamp){
        this.data = data;
        this.timestamp = timestamp ? timestamp : (new Date()).getTime();
    }
}


// 3 秒
let defaultTimeOut = 3000
let cache = {};
let gcTimer;


/**
 * 可设置超时的队列
 */
class Queue {

    static triggerGc(){
        if( gcTimer ){
            // 当开启 gcTimer 时检测 cache 是否为空
            let need = false;
            for ( let k in cache ){
                // 为了防止占用太久时间
                // 只回收一部分
                if( cache[k].clearData() ){
                    if ( 0 == cache[k].length ){
                        delete cache[k];
                    }
                    need = true;
                    break;
                }
            }
            if( !need ){
                clearInterval(gcTimer);
                gcTimer = false;
            }
        }else{
            gcTimer = setTimeout(() => {
                Queue.triggerGc()
            }, 60000)
        }
    }

    static has(owner){
        if( !cache[owner] ) {
            return 0;
        }else{
            return cache[owner].length
        }
    }

    static setData( owner , data){
        if( !cache[owner] ){
            cache[owner] = new Queue(defaultTimeOut)
        }else{
            cache[owner].clearData();
        }
        cache[owner].push(new Entry(data))
    }
    static getAllData( owner ){
        if( !cache[owner] ){
            return []
        }else{
            cache[owner].clearData();
            return cache[owner].getAllData()
        }
    }


    constructor( timeout, maxlen ){
        this.q = []
        this.timeout = timeout;
        this.maxlen = maxlen;
    }

    // 去除超时数据
    clearData(){
        let deadline = (new Date()).getTime() - this.timeout;
        for( let i = this.q.length -1 ; i >= 0 ; i -- ){
            let e = this.q[i];
            if( e.timestamp  < deadline){
                this.q.splice(0,i);
                return true;
            }
        }
        return false;
    }

    getAllData(){
        let ret = [];
        for ( let e of this.q ){
            ret.push(e.data);
        }
        this.q = [];
        return ret;
    }

    push(data){
        if( this.maxlen ){
            if( this.q.length == this.maxlen ){
                this.q.splice(0,1);
            }
        }
        this.q.push(data)
    }



    get length(){
        return this.q.length;
    }
}


module.exports = Queue